﻿// owner 蒋家伟
#include "QueryableListTest.h"

// std
#include <memory>

#include "UnitTestDataDefine.h"
#include "StringUtils.h"
#include "UnitTestUtils.h"
#include "Dbg_Warn_Define.h"

using namespace std;
using namespace jsdk;

namespace
{
    template<typename Key, typename Value>
    void InitQueryableList(const std::vector<std::pair<Key, Value>>& input, QueryableList<Key, Value>& outQueryableList)
    {
        for (int i = 0; i < 10; i++)
        {
            outQueryableList.emplace_back(input[i].first, std::move(input[i].second));
        }
    }

    template<typename Key, typename Value>
    bool TestCurrentData(const std::vector<std::pair<Key, Value>>& input, const QueryableList<Key, Value>& outQueryableList, const std::wstring& prefixErrorMsg)
    {
        int index = 0;
        for (auto& iter : outQueryableList)
        {
            DBG_WARN_AND_RETURN_FALSE_UNLESS(iter.first == input[index].first, UnitTestUtils::combineErrorTestMsg(iter.first, input[index].first, prefixErrorMsg), L"蒋家伟", L"2023-07-19");
            DBG_WARN_AND_RETURN_FALSE_UNLESS(iter.second == input[index].second, UnitTestUtils::combineErrorTestMsg(iter.second, input[index].second, prefixErrorMsg), L"蒋家伟", L"2023-07-19");
            index++;
        }
        return true;
    }
}

UNIT_TEST_START(jsdk, QueryableListTest)
{
    QueryableListTest test;
    bool success = test.testInsertOrder();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"测试插入顺序失败", L"jiangjiawei", L"2023-07-19");

    success = test.testEraseOrder();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"测试删除失败", L"jiangjiawei", L"2023-07-19");

    success = test.testFrontAndBackInsert();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"测试首尾插入失败", L"jiangjiawei", L"2023-07-19");

    success = test.testMoveAndClear();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"测试移动语义和clear失败", L"jiangjiawei", L"2023-07-19");

    success = test.testValueIsUniquePtr();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"测试unique_ptr失败", L"jiangjiawei", L"2023-07-19");
    return true;
}

bool jsdk::QueryableListTest::testInsertOrder() const
{
    std::vector<std::pair<int, std::string>> res = { { 1, "1" },{ 2, "2" },{ 3, "3" },{ 4, "4" },{ 5, "5" },{ 0, "0" }};
    // 常规类型测试
    QueryableList<int, std::string> defaultTest;
    ::InitQueryableList(m_testSet, defaultTest);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(defaultTest.size() == res.size(), UnitTestUtils::combineErrorTestMsg(defaultTest.size(), res.size(), L"插入测试的结果出现错误，容器大小不正确, "), L"蒋家伟", L"2023-07-19");
    if (!TestCurrentData(res, defaultTest, L"插入测试的数据顺序不正确, "))
    {
        return false;
    }

    int number = -1;
    for (auto iter = defaultTest.begin(); iter != defaultTest.end();)
    {
        if (iter->first >= 3)
        {
            auto pair = defaultTest.insert(++iter, number, "*");
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pair.second, UnitTestUtils::combineErrorTestMsg(false, true, L"插入出现错误其内容：<" + StringUtils::toWString(number) + L", *>"), L"蒋家伟", L"2023-07-19");
            iter = pair.first;
            number--;
        }
        else
        {
            iter++;
        }
    }
    std::vector<std::pair<int, std::string>> res2 = { { 1, "1" },{ 2, "2" },{ 3, "3" },{ -1, "*" } ,{ 4, "4" },{ -2, "*" } ,{ 5, "5" },{ -3, "*" } ,{ 0, "0" } };
    return TestCurrentData(res2, defaultTest, L"插入一组测试的数据顺序不正确, ");
}

bool jsdk::QueryableListTest::testEraseOrder() const
{
    // 常规类型测试
    QueryableList<int, std::string> defaultTest;
    ::InitQueryableList(m_testSet, defaultTest);
    auto iter = defaultTest.find(5);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(iter!= defaultTest.end(), UnitTestUtils::combineErrorTestMsg(false, true, L"查找key为5出现错误, "), L"蒋家伟", L"2023-07-19");
    bool success = defaultTest.erase(5);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, UnitTestUtils::combineErrorTestMsg(false, true, L"删除key为5出现错误, "), L"蒋家伟", L"2023-07-19");
    iter = defaultTest.find(5);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(iter == defaultTest.end(), UnitTestUtils::combineErrorTestMsg(false, true, L"key = 5已经删除,不应该找到5, "), L"蒋家伟", L"2023-07-19");
    std::vector<std::pair<int, std::string>> res = { { 1, "1" },{ 2, "2" },{ 3, "3" },{ 4, "4" },{ 0, "0" } };
    if (!TestCurrentData(res, defaultTest, L"删除数据5后测试数据不正确，"))
    {
        return false;
    }

    iter = defaultTest.find(2);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(iter != defaultTest.end(), UnitTestUtils::combineErrorTestMsg(false, true, L"查找key为2出现错误, "), L"蒋家伟", L"2023-07-19");
    iter = defaultTest.erase(iter);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(iter!= defaultTest.end(), UnitTestUtils::combineErrorTestMsg(false, true, L"删除key为2出现错误, "), L"蒋家伟", L"2023-07-19");
    iter = defaultTest.find(2);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(iter == defaultTest.end(), UnitTestUtils::combineErrorTestMsg(true, false, L"key = 2已经删除,不应该找到2, "), L"蒋家伟", L"2023-07-19");

    std::vector<std::pair<int, std::string>> res2 = { { 1, "1" },{ 3, "3" },{ 4, "4" },{ 0, "0" } };
    if (!TestCurrentData(res2, defaultTest, L"删除数据2后测试数据不正确，"))
    {
        return false;
    }

    for (auto iter = defaultTest.begin(); iter != defaultTest.end(); )
    {
        if (iter->first > 2)
        {
            iter = defaultTest.erase(iter);
        }
        else
        {
            iter++;
        }
    }

    std::vector<std::pair<int, std::string>> res3 = { { 1, "1" },{ 0, "0" } };
    return TestCurrentData(res3, defaultTest, L"删除数据3,4后测试数据不正确，");

}

bool jsdk::QueryableListTest::testFrontAndBackInsert() const
{
    // 常规类型测试
    QueryableList<int, std::string> defaultTest;
    ::InitQueryableList(m_testSet, defaultTest);

    bool success = defaultTest.emplace_back(1, "1");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(!success, UnitTestUtils::combineErrorTestMsg(true, false, L"在尾部插入一个已存在的数字1"), L"蒋家伟", L"2023-07-19");

    success = defaultTest.emplace_back(7, "7");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, UnitTestUtils::combineErrorTestMsg(false, true, L"在尾部插入一个不存在的数字7"), L"蒋家伟", L"2023-07-19");

    success = defaultTest.emplace_front(1, "1");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(!success, UnitTestUtils::combineErrorTestMsg(true, false, L"在首部插入一个已存在的数字1"), L"蒋家伟", L"2023-07-19");

    success = defaultTest.emplace_front(6, "6");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, UnitTestUtils::combineErrorTestMsg(false, true, L"在尾部插入一个不存在的数字6"), L"蒋家伟", L"2023-07-19");

    std::vector<std::pair<int, std::string>> res = { {6, "6"} ,{ 1, "1" },{ 2, "2" },{ 3, "3" },{ 4, "4" },{ 5, "5" },{ 0, "0" },{7, "7"} };
    return TestCurrentData(res, defaultTest, L"首尾插入不同的结果");
}

bool jsdk::QueryableListTest::testMoveAndClear() const
{
    // 常规类型测试
    QueryableList<int, std::string> defaultTest;
    ::InitQueryableList(m_testSet, defaultTest);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(defaultTest.size() == 6, UnitTestUtils::combineErrorTestMsg(defaultTest.size(), 6, L"初始化queryablelist，其size"), L"蒋家伟", L"2023-07-19");
    QueryableList<int, std::string> test2 = std::move(defaultTest);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(defaultTest.empty(), UnitTestUtils::combineErrorTestMsg(defaultTest.size(), 0, L"移动语义后源对象，其size"), L"蒋家伟", L"2023-07-19");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(test2.size() == 6, UnitTestUtils::combineErrorTestMsg(test2.size(), 6, L"移动语义后目标对象，其size"), L"蒋家伟", L"2023-07-19");
    test2.clear();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(test2.empty(), UnitTestUtils::combineErrorTestMsg(test2.size(), 0, L"目标对象clear后，其size"), L"蒋家伟", L"2023-07-19");
    return true;
}

bool jsdk::QueryableListTest::testValueIsUniquePtr() const
{
    QueryableList<int, std::unique_ptr<int>> defaultTest;
    std::unique_ptr<int> upTest1 = std::make_unique<int>(1);
    defaultTest.emplace_front(1, std::move(upTest1));
    defaultTest.emplace_front(2, std::make_unique<int>(2));
    defaultTest.emplace_front(3, std::make_unique<int>(3));
    defaultTest.emplace_front(4, std::make_unique<int>(4));

    std::vector<std::pair<int, std::unique_ptr<int>>> res;
    res.push_back(std::make_pair(4, std::make_unique<int>(4)));
    res.push_back(std::make_pair(3, std::make_unique<int>(3)));
    res.push_back(std::make_pair(2, std::make_unique<int>(2)));
    res.push_back(std::make_pair(1, std::make_unique<int>(1)));

    int index = 0;
    for (auto& iter : defaultTest)
    {
        DBG_WARN_AND_RETURN_FALSE_UNLESS(iter.first == res[index].first, UnitTestUtils::combineErrorTestMsg(iter.first, res[index].first, L"测试unique_ptr"), L"蒋家伟", L"2023-07-19");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(*(iter.second) == *(res[index].second), UnitTestUtils::combineErrorTestMsg(*(iter.second), *(res[index].second), L"测试unique_ptr"), L"蒋家伟", L"2023-07-19");
        index++;
    }
    return true;
};

jsdk::QueryableListTest::QueryableListTest():m_testSet({ { 1, "1" },{ 2, "2" },{ 3, "3" },{ 4, "4" },{ 5, "5" },{ 2, "2" },{ 3, "3" },{ 1, "1" },{ 0, "0" },{ 2, "2" } })
{
}
